// 自动绑定子节点的node和component
import {CCComponent} from "../../base/CCComponent";

const bind_to_root_prefix = '@';
const ignore_prefix = '#';

let Skip_Type = cc.Enum({
    NOT_SKIP: 0,        // 不用跳过
    SKIP_CHILD: 1,      // 跳过子节点
    SKIP_ALL: 2,        // 跳过自己包括子节点
});


const {ccclass, property} = cc._decorator;
/*
*ClassName:CCComponent
*Description:基础组件
*Date:2019/10/25 11:34
*/
@ccclass
export default class BindComponent extends CCComponent {

    /***是否需要绑定组件*/
    public isBindComponent :boolean = true;

    protected onLoad(): void {
        if(!this.isBindComponent){
            return;
        }
        bindNode(this, this.node);
    }
}

export function bindNode(root: any, node: cc.Node) {
    let children = node.children;
    for (let i = 0; i < children.length; i++) {
        const child = children[i];
        let skipType = _getSkipType(child.name);
        //console.error("child name = ", child.name, "/skipType=", skipType);
        if (skipType === Skip_Type.SKIP_ALL) {
            continue;
        }

        let name = _getNodeName(child);
        //console.error("name[0] = ", name[0], "/name=", name,"/bind_to_root_prefix",bind_to_root_prefix);
        if (name[0] === bind_to_root_prefix) {
            // 绑定$前缀子节点到root
            if (!root[name]) {
                root[name] = child;
                // 绑定组件到root node节点上
                _bindComponent(root, child);
            }
        } else {
            // 绑定非前缀子节点到父节点
            name = '@' + name;

            // 绑定组件到自身node节点上
            _bindComponent(node, child);
        }

        if (!node[name]) {
            node[name] = child;
        }
        //console.log("...........node[name] = ", name, "/child=", child);
        if (skipType !== Skip_Type.SKIP_CHILD) {
            bindNode(root, child);
        }
    }
}

// 跳过子节点
export function _getSkipType(name :string) {
    if (!name || name.length <= 0) {
        return Skip_Type.SKIP_ALL;
    }

    // !开头
    if (name[0] === ignore_prefix) {
        return Skip_Type.SKIP_ALL;
    }

    // $开头
    if (name[0] === bind_to_root_prefix) {
        if (name.length > 1 && name[1] === ignore_prefix) {
            // $!开头
            return Skip_Type.SKIP_CHILD;
        }
    }

    return Skip_Type.NOT_SKIP;
}

export function _bindComponent(parent:any, node) {
    let nodeName = _getNodeName(node);
    if (nodeName[0] !== bind_to_root_prefix) {
        nodeName = '@' + nodeName;
    }

    for (let index = 0; index < node._components.length; index++) {
        const component = node._components[index];

        if (component === this) {
            continue;
        }

        let compName = _getComponentName(component);
        let name = nodeName + '_' + compName;
        //let name = nodeName + '_' + compName.toLocaleLowerCase();
        parent[name] = component;

        // 检查组件 onBind 函数,通知组件,target 对象在绑定自己
        if (_isFunction(component.onBind)) {
            component.onBind(parent);
        }
    }
}

/**
 * 获取组件名字
 * @param {cc.Component} component
 */
export function _getComponentName(component) {
    return component.name.match(/<.*>$/)[0].slice(1, -1);
}

/**
 * 获取Node名字
 * @param {cc.Component} node
 */
export function _getNodeName(node) {
    let name = node.name;
    name = name.replace(/[^0-9a-zA-Z@#$&\_]/, '');
    return name;
}

export function _isFunction(value) {
    return typeof value === 'function';
}